"""
Дополнительные функции для движка VK.

- Получение ID пользователя различными способами
- Получение словаря пользователей чата

Author: Milinuri Nirvalen
Ver: 1.4 (13)
"""

from chiori.modules import Event, Context
from libs.nicknames import get_nick

import time
import re
from typing import Optional
from typing import Dict


Profiles = Dict[str, dict]
args = {"target": "пересланное сообщения; id123; ссылка; ник; имя (фамилия)"}

PLATFORMS = {1: "💻", 2: "🍎", 3: "🍎t", 4: "📱", 5: "📱*", 6:"🖥️", 7:"🌐"}
FIELDS = "bdate, online, last_seen, has_mobile"


# Вспомогательные функции для получения id
# ========================================

async def resolve_screen_name(ctx: Context, arg: str) -> str | None:
	res = await ctx.request("utils.resolveScreenName", screen_name=arg)
	if not res["error"] and res["response"]:
		return str(res["response"]["object_id"])

async def get_id_with_str(ctx: Context, arg: str) -> str | None:
	id_str = re.search(r"id(\d+)", arg)
	if id_str is not None:
		return id_str.groups()[0]

	screen_name = re.search(r"vk\.com/(\w{3,})", arg)

	return await resolve_screen_name(ctx,
		screen_name.groups()[0] if screen_name is not None else arg
	)


# Получение id пользователей
# ==========================

async def get_id(event: Event, ctx: Context,
	args: Optional[list[str]]=None) -> (str, str):
	if args is None:
		args = ctx.args

	reply_id = event.get("reply.from_id")
	if reply_id:
		return str(reply_id), ctx.sargs

	for i, x in enumerate(args):
		user_id = await get_id_with_str(ctx, x)

		if user_id is not None:
			return user_id, " ".join(args[i+1: ])

	return None, ctx.sargs

async def get_ids(event: Event, ctx: Context,
	args: Optional[list[str]]=None) -> list[str]:
	if args is None:
		args = ctx.args

	ids = []

	reply_id = event.get("reply.from_id")
	if reply_id:
		ids.append(str(reply_id))

	for x in args:
		user_id = await get_id_with_str(ctx, x)
		if user_id is not None:
			ids.append(user_id)

	return ids


# Получаени профилей пользователей
# ================================

def convert_profiles(profiles: list[dict], added: list[dict]) -> Profiles:
	res = {}

	for u in profiles:
		f_name = u["first_name"]
		l_name = u["last_name"]
		name = ""

		if u.get("online"):
			if "platform" in u["last_seen"]:
				name += PLATFORMS[u["last_seen"]["platform"]]
			else:
				name += "🔥"

		if u.get("deactivated"):
			name += "👻"

		nick = get_nick(str(u["id"]))
		if nick is None:
			name += f"{f_name.capitalize()} {l_name.capitalize()}"
		else:
			name += nick

		res[str(u["id"])] = u
		res[str(u["id"])]["name"] = name

	for u in added:
		if u["member_id"] < 0:
			continue

		if str(u["member_id"]) in res:
			res[str(u["member_id"])].update(u)

		if u.get("join_date") is None:
			res[str(u["member_id"])]["join_date"] = time.time()

	return res

async def get_profiles(event: Event, ctx: Context,
	ids: Optional[list[str]]=None) -> Profiles:
	if ids is None:
		ids = []

	raw_profiles = []
	items = []

	if ids:
		ids = list(map(str, ids))
		res = await ctx.request(
			"users.get", user_ids=",".join(ids), fields=FIELDS)
		if not res["error"]:
			raw_profiles = res["response"]
	else:
		res = await ctx.request(
			"messages.getConversationMembers",
			peer_id=event.get("to.id"), field=FIELDS)

		if not res["error"]:
			raw_profiles = res["response"]["profiles"]
			items = res["response"]["items"]

	return convert_profiles(raw_profiles, items)
